{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import Libraries\n",
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>longitude</th>\n",
       "      <th>latitude</th>\n",
       "      <th>housing_median_age</th>\n",
       "      <th>total_rooms</th>\n",
       "      <th>total_bedrooms</th>\n",
       "      <th>population</th>\n",
       "      <th>households</th>\n",
       "      <th>median_income</th>\n",
       "      <th>ocean_proximity</th>\n",
       "      <th>median_house_value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-122.23</td>\n",
       "      <td>37.88</td>\n",
       "      <td>41</td>\n",
       "      <td>880</td>\n",
       "      <td>129.0</td>\n",
       "      <td>322</td>\n",
       "      <td>126</td>\n",
       "      <td>8.3252</td>\n",
       "      <td>NEAR BAY</td>\n",
       "      <td>452600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-122.22</td>\n",
       "      <td>37.86</td>\n",
       "      <td>21</td>\n",
       "      <td>7099</td>\n",
       "      <td>1106.0</td>\n",
       "      <td>2401</td>\n",
       "      <td>1138</td>\n",
       "      <td>8.3014</td>\n",
       "      <td>NEAR BAY</td>\n",
       "      <td>358500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-122.24</td>\n",
       "      <td>37.85</td>\n",
       "      <td>52</td>\n",
       "      <td>1467</td>\n",
       "      <td>190.0</td>\n",
       "      <td>496</td>\n",
       "      <td>177</td>\n",
       "      <td>7.2574</td>\n",
       "      <td>NEAR BAY</td>\n",
       "      <td>352100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-122.25</td>\n",
       "      <td>37.85</td>\n",
       "      <td>52</td>\n",
       "      <td>1274</td>\n",
       "      <td>235.0</td>\n",
       "      <td>558</td>\n",
       "      <td>219</td>\n",
       "      <td>5.6431</td>\n",
       "      <td>NEAR BAY</td>\n",
       "      <td>341300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-122.25</td>\n",
       "      <td>37.85</td>\n",
       "      <td>52</td>\n",
       "      <td>1627</td>\n",
       "      <td>280.0</td>\n",
       "      <td>565</td>\n",
       "      <td>259</td>\n",
       "      <td>3.8462</td>\n",
       "      <td>NEAR BAY</td>\n",
       "      <td>342200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   longitude  latitude  housing_median_age  total_rooms  total_bedrooms  \\\n",
       "0    -122.23     37.88                  41          880           129.0   \n",
       "1    -122.22     37.86                  21         7099          1106.0   \n",
       "2    -122.24     37.85                  52         1467           190.0   \n",
       "3    -122.25     37.85                  52         1274           235.0   \n",
       "4    -122.25     37.85                  52         1627           280.0   \n",
       "\n",
       "   population  households  median_income ocean_proximity  median_house_value  \n",
       "0         322         126         8.3252        NEAR BAY              452600  \n",
       "1        2401        1138         8.3014        NEAR BAY              358500  \n",
       "2         496         177         7.2574        NEAR BAY              352100  \n",
       "3         558         219         5.6431        NEAR BAY              341300  \n",
       "4         565         259         3.8462        NEAR BAY              342200  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Import Dataset\n",
    "dataset = pd.read_csv(\"housing.csv\")\n",
    "dataset.head() # Print first 5 observations from dataset using head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "longitude             False\n",
       "latitude              False\n",
       "housing_median_age    False\n",
       "total_rooms           False\n",
       "total_bedrooms         True\n",
       "population            False\n",
       "households            False\n",
       "median_income         False\n",
       "ocean_proximity       False\n",
       "median_house_value    False\n",
       "dtype: bool"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Check in which column contains nan values\n",
    "dataset.isnull().any()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sample feature vector:  [-122.22 37.86 21 7099 1106.0 2401 1138 8.3014 'NEAR BAY']\n"
     ]
    }
   ],
   "source": [
    "# Separate features and labels\n",
    "features = dataset.iloc[:,:-1].values\n",
    "label = dataset.iloc[:,-1].values.reshape(-1,1)\n",
    "print(\"Sample feature vector: \", features[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Perform Imputation with strategy=mean\n",
    "#from sklearn.preprocessing import Imputer\n",
    "from sklearn.impute import SimpleImputer\n",
    "imputerNaN = SimpleImputer(strategy=\"mean\")\n",
    "features[:,[4]] = imputerNaN.fit_transform(features[:,[4]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Features requiring encoding:  {'NEAR BAY', 'NEAR OCEAN', 'INLAND', 'ISLAND', '<1H OCEAN'}\n",
      "Sample feature vector:  [-122.22 37.86 21 7099 1106.0 2401 1138 8.3014 3]\n",
      "No. of features:  9\n",
      "Sample feature vector after encoding:  [0.0, 0.0, 0.0, 1.0, 0.0, -122.22, 37.86, 21, 7099, 1106.0, 2401, 1138, 8.3014]\n",
      "No. of features after encoding:  13\n"
     ]
    }
   ],
   "source": [
    "# Perform Label Encoding and Onehot Encoding on categorical values present in the features\n",
    "from sklearn.preprocessing import LabelEncoder,OneHotEncoder\n",
    "print(\"Features requiring encoding: \", set(features[:,8]))\n",
    "features[:,8] = LabelEncoder().fit_transform(features[:,8])\n",
    "print(\"Sample feature vector: \", features[1])\n",
    "print(\"No. of features: \", len(features[1]))\n",
    "\n",
    "from sklearn.compose import ColumnTransformer \n",
    "ct = ColumnTransformer([(\"Name\", OneHotEncoder(),[8])], remainder=\"passthrough\") # The last arg ([0]) is the list of columns you want to transform in this step\n",
    "features = ct.fit_transform(features).tolist()\n",
    "\n",
    "#features = OneHotEncoder(categorical_features=[8]).fit_transform(features).toarray()\n",
    "print(\"Sample feature vector after encoding: \", features[1])\n",
    "print(\"No. of features after encoding: \", len(features[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Score for Training data: 0.8206121576672761\n",
      "Model Score for Testing data: 0.7754096029715711\n"
     ]
    }
   ],
   "source": [
    "X,y=features,label # Purpose of this copying variables is that trees doesn't requires scaling while others \"may be\"\n",
    "# Split into training set and testing set in every model building cause of \"random_state\" present in the \"train_test_split\"\n",
    "from sklearn.model_selection import train_test_split as tts\n",
    "X_train,X_test,y_train,y_test = tts(X,y,test_size=0.2,random_state=5)\n",
    "\n",
    "# Random Forest Tree Regression\n",
    "from sklearn.ensemble import RandomForestRegressor\n",
    "depth = 9\n",
    "no_of_estim = 10\n",
    "model_random = RandomForestRegressor(n_estimators=no_of_estim, random_state=20, max_depth=depth)\n",
    "model_random.fit(X_train,y_train.ravel())\n",
    "\n",
    "# Perform prediction and model score\n",
    "y_pred = model_random.predict(X_test)\n",
    "from sklearn.metrics import r2_score\n",
    "print(\"Model Score for Training data: {}\".format(model_random.score(X_train,y_train)))\n",
    "print(\"Model Score for Testing data: {}\".format(r2_score(y_test,y_pred)))\n",
    "#print(\"Root Mean Squared Error is {}\".format(np.sqrt(mean_squared_error(y_test,y_pred))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Export pickle model\n",
    "import pickle\n",
    "pickle.dump(model_random, open('pickle_model.pickle', 'wb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test input:  [ 0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00  1.0000e+00 -1.1707e+02\n",
      "  3.2570e+01  1.4000e+01  1.5270e+03  3.5700e+02  1.2240e+03  3.6300e+02\n",
      "  2.7361e+00]\n",
      "Expected output:  133242.04011201978\n",
      "Dumped input as np array in input.npy\n"
     ]
    }
   ],
   "source": [
    "test_input = np.array(X_test[0])\n",
    "test_output = y_pred[0]\n",
    "\n",
    "print(\"Test input: \", test_input)\n",
    "print(\"Expected output: \", test_output)\n",
    "\n",
    "with open('input.npy', 'wb') as f:\n",
    "    np.save(f, test_input)\n",
    "print(\"Dumped input as np array in input.npy\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
